/*
 * @Author: xiaosihan 
 * @Date: 2024-12-02 01:16:13 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2024-12-02 08:12:51
 */
import { NameNum } from "#/type";
import commonService from "@/api/services/commonService";
import userDesignService from "@/api/services/userDesignService";
import utilsServer from "@/api/services/utilsServer";
import editorStore from "@/editorComponent/editorStore";
import preview2DRenderer from "@/editorComponent/preview2DRenderer";
import textureManager from "@/editorComponent/textureManager";
import thumb3DRenderer from "@/editorComponent/thumb3DRenderer";
import FabricText from "@/myFabric/FabricText";
import utils from "@/utils/utils";
import { DeleteOutlined, PlusOutlined } from "@ant-design/icons";
import CloseCircleOutlined from "@ant-design/icons/lib/icons/CloseCircleOutlined";
import { Button, Input, message, Select } from "antd";
import { cloneDeep, debounce, get } from "lodash";
import { autorun, toJS } from "mobx";
import { ReactNode, useEffect, useRef, useState } from "react";
import nameNumStore from "../nameNumStore";
import styles from "./step3.module.less";
import userStore from "@/store/userStore";
import ExcelJS from "exceljs";

const { Option } = Select;

interface Iprops {
  children?: ReactNode
}

// 步骤3
export default function Step3() {

  const dom = useRef<HTMLDivElement | null>(null);
  const [loadding, setLoadding] = useState(false);
  const [addName, setAddName] = useState(editorStore.addName);
  const [addNum, setAddNum] = useState(editorStore.addNum);
  const [nameNumList, setNameNumList] = useState(editorStore.nameNumList);
  const [goodsSizeList, setGoodsSizeList] = useState<Array<string>>([]);
  const [editorNameNum, setEditorNameNum] = useState(editorStore.editorNameNum);

  useEffect(() => {

  }, []);

  useEffect(() => autorun(() => {
    setAddName(editorStore.addName);
    setAddNum(editorStore.addNum);
    setEditorNameNum(editorStore.editorNameNum);
    setNameNumList(toJS(editorStore.nameNumList));
    const { goodsData } = editorStore;
    if (goodsData) {
      const sizePrice = toJS(goodsData.sizePrice) || [];
      setGoodsSizeList(sizePrice.map(({ size }) => size));
    }
  }, { delay: 10 }), []);

  const length = nameNumList.length;
  const sizeNum: { [key: string]: number } = {};
  nameNumList.map(nameNum => {
    if (sizeNum[nameNum.size]) {
      sizeNum[nameNum.size]++;
    } else {
      sizeNum[nameNum.size] = 1;
    }
  });

  //下载数据
  const downData = async () => {
    const XLSX = await import("xlsx");
    // 假设这是你的JSON数据
    // const jsonData = [
    //   { name: "John", age: 30, city: "New York" },
    //   { name: "Doe", age: 50, city: "Los Angeles" },
    //   { name: "Jane", age: 25, city: "Chicago" }
    // ];

    const excelJson: Array<any> = cloneDeep(nameNumList);
    const { name = "", sizePrice = [] } = editorStore.goodsData || {};
    if (excelJson[0]) {
      excelJson[0][`${name}-可选尺码:${sizePrice.map(s => s.size).join(",")}`] = "";
    } else {
      excelJson.push({
        name: "",
        num: "",
        size: "",
        [`${name}-可选尺码:${sizePrice.map(s => s.size).join(",")}`]: ""
      })
    }
    // 将JSON转换为工作表
    const worksheet = XLSX.utils.json_to_sheet(excelJson);
    worksheet['!cols'] = [
      { wch: 10 }, // 第一列宽度
      { wch: 10 }, // 第二列宽度
      { wch: 10 }, // 第三列宽度
      { wch: 100 }, // 第四列宽度，这里设置为20
    ];

    // 创建一个新的工作簿并添加工作表
    const workbook = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(workbook, worksheet, "Sheet1");

    // 导出为Excel文件
    XLSX.writeFile(workbook, "名字号码.xlsx");

  }

  //上传数据
  const updata = async () => {
    const file = await utils.selectFile('.xlsx');
    const XLSX = await import("xlsx");
    if (file) {

      var reader = new FileReader();
      reader.onload = function (e) {
        //@ts-ignore
        var arrayBuffer = e.target.result;
        // 使用xlsx库解析ArrayBuffer数据
        var workbook = XLSX.read(arrayBuffer, { type: 'array' });
        // 获取工作表名数组
        const sheetNameArray = workbook.SheetNames;
        // 获取第一个工作表
        const firstSheet = workbook.Sheets[sheetNameArray[0]];
        // 将工作表转换为JSON
        const [keys, ...datas] = XLSX.utils.sheet_to_json(firstSheet, { header: 1 });
        const data = datas.map(d => {
          const dat: { [key: string]: any } = {};
          (d as Array<any>).map((v, i) => {
            if ((keys as Array<string>)[i] === 'size') {
              //补全尺码参数
              const V = (v || "").toUpperCase();
              dat[(keys as Array<string>)[i]] = goodsSizeList.includes(V) ? V : goodsSizeList[0];
            } else {
              dat[(keys as Array<string>)[i]] = v;
            }
          });

          dat.name = dat.name || '名字';
          dat.num = dat.num || "00";
          dat.size = dat.size;

          return dat as NameNum;
        });
        editorStore.setNameNumList(data);
      };
      reader.readAsArrayBuffer(file);
    }
  }

  // 名字和号码添加到购物车
  const addShopCar = async () => {

    const token = userStore.getState().userToken;
    if (!token.accessToken) {
      userStore.getState().actions.setShowLogin(true);
      return;
    }

    //没有添加号码和名字的提示
    if (nameNumList.length === 0) {
      message.error("请添加名字和号码");
      return;
    }

    setLoadding(true);
    for (let nameNum of nameNumList) {
      for (let side of ['front', 'back', 'left_front', 'right_front', 'left_back', 'right_back']) {
        //修改数据
        const frontFabricData = editorStore.design_data.designData[side];
        if (frontFabricData) {
          frontFabricData.objects.map((o: any) => {
            if (o.name === 'name') {
              o.text = nameNum.name;
            } else if (o.name === 'num') {
              o.text = String(nameNum.num);
            }
            if (['name', 'num'].includes(o.name)) {
              const text = new FabricText();
              text.set(o);
              const w = text.getScaledWidth();
              const h = text.getScaledHeight();
              const scale = Math.min(
                o.originWidth / w,
                o.originHeight / h,
              );
              text.fontSize! *= scale;
              Object.assign(o, text.toJSON());
            }
          });
          await textureManager.updataTextByFabricJSON(side, frontFabricData);
        }
      }

      editorStore.updataTime();

      const allThumbFiles = await preview2DRenderer.getAllthumbFile();
      const fontFile = await thumb3DRenderer.getThumbFile();
      const backFile = await thumb3DRenderer.getBackThumbFile();
      const [fontUrl, backUrl, ...previewThumb] = await Promise.all([
        utilsServer.uploadOss(fontFile),
        utilsServer.uploadOss(backFile),
        ...allThumbFiles.map((file) => {
          return utilsServer.uploadOss(file);
        }),
      ]);
      const design_data = toJS(editorStore.design_data);
      design_data.thumbs = [fontUrl, backUrl];
      design_data.previewThumb = previewThumb;
      const hasFront = (get(design_data, ['designData', 'front', 'objects', 'length']) || 0) > 0;
      const hasBack = (get(design_data, ['designData', 'back', 'objects', 'length']) || 0) > 0;
      if (hasFront && hasBack) {
        design_data.printArea = 'double';
      } else if (!hasFront && hasBack) {
        design_data.printArea = 'back';
      } else {
        design_data.printArea = 'front';
      }
      try {
        const result = await userDesignService.saveProduct(design_data);
        const id = result.id;
        await commonService.addCartApi({ num: 1, size: nameNum.size, fpId: id })
      } catch (error) {
        console.log(error);
      }
    }

    //名字号码还原
    for (let side of ['front', 'back', 'left_front', 'right_front', 'left_back', 'right_back']) {
      const frontFabricData = editorStore.design_data.designData[side];
      if (frontFabricData) {
        frontFabricData.objects.map((o: any) => {
          if (o.name === 'name') {
            o.text = "名字";
          } else if (o.name === 'num') {
            o.text = "00";
          }
        });
        await textureManager.updataTextByFabricJSON(side, frontFabricData);
      }
    }
    editorStore.updataTime();

    // 跳转到购物车界面
    window.location.href = `/#/admin/cart`;
    setLoadding(false);
  }

  return (
    <div ref={dom} className={styles.step3} >

      <div
        className={styles.title}
        onClick={() => {
          nameNumStore.setStep(2);
        }}
      >
        {"<"}&nbsp;&nbsp;&nbsp;{"输入姓名 号码 尺码"}
      </div>

      <div className={styles.listItem} >
        <span className={styles.lable} >名字</span>
        <span className={styles.input} >号码</span>
        <span className={styles.input} >尺码</span>
      </div>

      <div className={styles.list} >
        {
          nameNumList.map((nameNum, i) => {
            return (
              <div className={styles.listItem} key={i} >
                <span className={styles.lable} >
                  <Input
                    disabled={!addName}
                    // key={nameNum.name}
                    style={{ width: 100 }}
                    defaultValue={addName ? nameNum.name : ""}
                    placeholder="输入名字"
                    maxLength={15}
                    // onBlur={e => {
                    //   editorStore.updataNameNum(i, { name: e.target.value });
                    // }}
                    onFocus={() => {
                      editorStore.perViewNameNum(i, 'name');
                    }}
                    onChange={debounce((e) => {
                      editorStore.updataNameNum(i, { name: (e.target.value || "").toUpperCase() });
                      editorStore.perViewNameNum(i, 'name');
                    }, 100)}
                  />
                </span>
                <span className={styles.input} >
                  <Input
                    disabled={!addNum}
                    style={{ width: 70 }}
                    defaultValue={addNum ? nameNum.num : ""}
                    placeholder="号码"
                    maxLength={15}
                    onChange={debounce((e) => {
                      editorStore.updataNameNum(i, { num: e.target.value || '0' });
                      editorStore.perViewNameNum(i, 'num');
                    }, 100)}
                    onFocus={() => {
                      editorStore.perViewNameNum(i, 'num');
                    }}
                  />
                </span>
                <span className={styles.input} >
                  {
                    editorNameNum ?
                      <span>
                        {nameNum.size}&nbsp;&nbsp;
                        <CloseCircleOutlined
                          className={styles.del}
                          onClick={() => {
                            editorStore.delNameNum(i);
                          }}
                        />
                      </span>
                      :
                      <Select
                        value={nameNum.size}
                        style={{ width: 80 }}
                        onChange={size => {
                          editorStore.updataNameNum(i, { size });
                        }}
                      >
                        {
                          goodsSizeList.map((size, i) => {
                            return (
                              <Option key={i} value={size} >{size}</Option>
                            )
                          })
                        }
                      </Select>
                  }
                </span>
              </div>
            )
          })
        }
      </div>

      <div className={styles.btns} >
        <Button
          ghost
          type="primary"
          className={styles.addMore}
          onClick={() => {
            editorStore.addNameNum();
          }}
        >
          <PlusOutlined />
          添加更多
        </Button>
        <Button
          ghost
          type="primary"
          className={styles.editorList}
          onClick={() => {
            editorStore.setEditorNameNum(!editorNameNum);
          }}
        >
          <DeleteOutlined />
          {editorNameNum ? '取消编辑' : '编辑列表'}
        </Button>
      </div>

      <div className={styles.btns} >
        <Button ghost type="primary" onClick={() => downData()} >下载模版</Button>
        <Button ghost type="primary" onClick={() => updata()} >上传数据</Button>
      </div>

      <div className={styles.statistics} >
        总计: {length}个名字,{length}个号码,{length}个尺码
      </div>

      <div className={styles.statistics} >
        尺码 : {Object.keys(sizeNum).map(size => `(${sizeNum[size]}/${length})${size}`).join(",")}
      </div>

      <Button
        loading={loadding}
        type="primary"
        block
        className={styles.addShopCar}
        onClick={addShopCar}
      >
        加入购物车
      </Button>


    </div>
  );

}